﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using System.Diagnostics;

namespace Arroguella.Tiles
{
    public class MapGenerator
    {
        #region Constructor

        protected MapGenerator(Dictionary<Vector2, Tile> tileMap, Guid seed)
        {
            TileMap = tileMap ?? new Dictionary<Vector2, Tile>();

            random = new Random(seed.GetHashCode());
        }

        #endregion

        #region Events
        #endregion

        #region Methods

        /// <summary>
        /// Makes the map.
        /// </summary>
        public virtual void MakeMap(int level)
        {

        }

        /// <summary>
        /// Blocks all the tiles in the map, essentially making them walls.
        /// </summary>
        internal virtual void BlockAll()
        {
        }

        /// <summary>
        /// Carves out a room, setting the interior to just floor.
        /// </summary>
        /// <param name="roomRectangle">A vector storing the X, Y, Width, and Height options for the room.</param>
        internal virtual void CarveOutRoom(Vector4 roomRectangle)
        {
        }  

        /// <summary>
        /// Returns the Tile coordinates for the center of a room.
        /// </summary>
        /// <param name="room">A Vector4 representing a room with X, Y, Width, and Height parameters.</param>
        internal Vector2 CenterOf(Vector4 room)
        {
            int x = (int)room.X;
            int y = (int)room.Y;
            int width = (int)room.Z;
            int height = (int)room.W;

            int centerX = x + (width / 2);
            int centerY = y + (height / 2);

            Debug.Assert(centerX >= x && centerX <= x + width);
            Debug.Assert(centerY >= y && centerY <= y + height);

            return new Vector2(centerX, centerY);
        }
        
        /// <summary>
        /// Whether or not a Vector4 representing a rectangle or room intersects with another Vector4.
        /// </summary>
        internal bool Intersects(Vector4 a, Vector4 b)
        {
            Rectangle ra = new Rectangle((int)a.X, (int)a.Y, (int)a.Z, (int)a.W);
            Rectangle ba = new Rectangle((int)b.X, (int)b.Y, (int)b.Z, (int)b.W);

            return ra.Intersects(ba);
        }

        /// <summary>
        /// Returns a random integer from min to max (inclusive)
        /// </summary>
        internal static int RandomInt(int min, int max)
        {
            return random.Next(min, max + 1);
        }

        #endregion

        #region Properties

        internal Dictionary<Vector2, Tile> TileMap { get; set; }

        /// <summary>
        /// Gets the number of Tile Columns in the map,
        /// or the number of Tiles in the X-direction.
        /// </summary>
        internal int NumberOfTileColumns
        {
            get
            {
                int cols = -1;
                foreach (Vector2 coords in TileMap.Keys)
                {
                    if (coords.X > cols)
                    {
                        cols = (int)coords.X;
                    }
                }

                return cols;
            }
        }

        /// <summary>
        /// Gets the number of Tile Columns in the map,
        /// or the number of Tiles in the Y-direction.
        /// </summary>
        internal int NumberOfTileRows
        {
            get
            {
                int rows = -1;
                foreach (Vector2 coords in TileMap.Keys)
                {
                    if (coords.Y > rows)
                    {
                        rows = (int)coords.Y;
                    }
                }

                return rows;
            }
        }

        /// <summary>
        /// Returns the coordinates of the Tile at the center of the tile map.
        /// </summary>
        internal Vector2 CenterOfTileMap
        {
            get
            {
                int centerX = (int)(NumberOfTileColumns / 2);
                int centerY = (int)(NumberOfTileRows / 2);
                return new Vector2(centerX, centerY);
            }
        }

        private static Random random;

        #endregion
    }
}
